<?php
/**
 * user.php
 * 
 * Created on 2014-10-17
 * Create by Calvin.Wang
 */

namespace haibao\cms\data;

use haibao\frame\data\query\Condition;
use haibao\cms\model\filter\User as UserFilter;

class User extends \haibao\cms\data\BaseMysql{
	public function __construct(){
		parent::__construct('\haibao\cms\model\data\User');
	}
	
	public function getUserInfoByIds($userIds){
	    if(is_array($userIds)){
	        $userIdString = preg_replace('/\d+/','%s',implode(',',$userIds));
	        $sql = 'select Id,RealName,Email,DingUserId,LeaderId from User where Status = 1 and Id in ('.$userIdString.')';
	        $result = $this->query($sql,$userIds);
	    }else{
	        $sql = 'select Id,RealName,Email,DingUserId,LeaderId from User where Status = 1 and Id = %s';
	        $result = $this->query($sql,array($userIds));
	    }
	    $userInfo = array();
	    while($row = $result->fetch_assoc()){
	        $userInfo[$row['Id']] = $row;
	    }
	    return $userInfo;
	}
	
	public function backPassword($userId,$newPassword){
		$sql = 'update User set Password=%s,Status='.\haibao\cms\model\data\User::STATUS_ENABLE.' where Id=%s';
		$this->query($sql,array(md5($newPassword),$userId));
	}
	
	public function removeBackPasswordCode($userId){
		$cache = new \haibao\cms\cache\User();
		
		$cache->removeBackPasswordCode($userId);
	}
	
	public function saveBackPasswordTimes($userId,$times){
		$cache = new \haibao\cms\cache\User();
		
		$cache->saveBackPasswordTimes($userId,$times);
	}
	
	public function getBackPasswordTimes($userId){
		$cache = new \haibao\cms\cache\User();
	
		return $cache->getBackPasswordTimes($userId);
	}
	
	public function saveBackPasswordCode($userId,$code){
		$cache = new \haibao\cms\cache\User();
		
		$cache->saveBackPasswordCode($userId,$code);
	}
	
	public function getBackPasswordCode($userId){
		$cache = new \haibao\cms\cache\User();
		
		return $cache->getBackPasswordCode($userId);
	}
	
	/**
	 * 用户搜索
	 * @param \haibao\cms\model\filter\User $userFilter
	 */
	public function getAll($userFilter){
		return parent::getAll($userFilter);
	}
	
	/**
	 * 
	 * @param string $userName
	 * @return \haibao\cms\model\data\User
	 */
	public function getUserByName($userName){
		$model = null;
		$sql = 'select u.*,g.GroupId from User u left join UserGroup g on u.Id=g.UserId where u.UserName=%s';
		$result = $this->query($sql,array($userName));
		while ($result->fetch_assoc()){
			if (!$model){
				$model = new \haibao\cms\model\data\User();
				foreach($model->getKeyMap() as $keyName=>$keyType){
					if (!($keyType instanceof \haibao\frame\data\datafield\RelationOneField || $keyType instanceof \haibao\frame\data\datafield\RelationManyField)){
						$model->$keyName = $result->getData($keyType->getFieldName());
					}
				}
				$model->Groups = array();
			}
			$groupId = $result->getData('GroupId');
			if ($groupId){
				array_push($model->Groups,$groupId);
			}
		}
		return $model;
	}
	
	public function getUserById($id){
		$cache = new \haibao\cms\cache\User();
		$model = $cache->getUser($id);
		$model = null;
		if (!$model){
			//$sql = 'select u.*,g.GroupId from User u left join UserGroup g on u.Id=g.UserId where u.Id=%s';
			$sql = 'select u.*,g.GroupId,m.UserId as LowerUserId from `User` u left join UserGroup g on u.Id=g.UserId LEFT JOIN UserLeaderMap m on  m.LeaderId = u.Id where u.Id=%s';
			$result = $this->query($sql,array($id));
			while ($result->fetch_assoc()){
				if (!$model){
					$model = new \haibao\cms\model\data\User();
					foreach($model->getKeyMap() as $keyName=>$keyType){
						if (!($keyType instanceof \haibao\frame\data\datafield\RelationOneField || $keyType instanceof \haibao\frame\data\datafield\RelationManyField)){
							$model->$keyName = $result->getData($keyType->getFieldName());
						}
					}
					$model->Groups = array();
				}
				$groupId = $result->getData('GroupId');
				if ($groupId){
					array_push($model->Groups,$groupId);
				}
				
				$lowerUserId = $result->getData('LowerUserId');
				if($lowerUserId){
					if(!in_array($lowerUserId,$model->LowerUser)){
						array_push($model->LowerUser,$lowerUserId);
					}
				}
			}

			if($model){
				if($model->Groups) {
					
					$model->Groups = array_flip(array_flip($model->Groups));
					//取出用户同组的其他用户Id
					$sql = 'select g.* from UserGroup g where g.GroupId in ('.implode(',',$model->Groups).')  and g.UserId not in (select m.LeaderId FROM UserLeaderMap m where m.UserId = %s and m.UserId <> m.LeaderId) group BY g.UserId';

					$result = $this->query($sql,array($id));
					while ($result->fetch_assoc()){
						array_push($model->SameUser,$result->getData('UserId'));
					}
				} 
				if($model->LowerUser){
					$lowerUser = implode(',',$model->LowerUser);
					$sql = 'select * from User where Id in ('.$lowerUser.') and Status=%s';
					$result = $this->query($sql,array(\haibao\cms\model\data\User::STATUS_DIMISSION));
					while ($result->fetch_assoc()){
						array_push($model->DimissionUser,$result->getData('Id'));
					}
				}
			}
			
			$cache->setUser($model);
		}
		return $model;
	}
	
	/**
	 * @param \haibao\cms\model\data\User $model
	 */
	public function add($model){
		$this->beginTranscation();
		try {
			parent::add($model);
			
			if($model->Groups){
				$this->addUserGroups($model->Id, $model->Groups);
			}
			
			$sql = 'insert into UserLeaderMap(UserId, LeaderId)
					select UserId, LeaderId from (
						(select %s as UserId, LeaderId from UserLeaderMap where UserId = %s)
						union
						(select %s,%s from UserLeaderMap limit 1) 
					) a';
			$this->query($sql, array(
					$model->Id, $model->LeaderId, $model->Id, $model->Id,
			));
			
			if($model->LeaderId){
				$this->removeUserCacheById($model->LeaderId);
			}
		} catch (\Exception $e) {
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	public function updateStatus($id, $status){
		$this->beginTranscation();
		try {
			parent::updateById($id, array('Status'=>$status));
			
			$this->removeUserCacheById($id);
		} catch (\Exception $e) {
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	public function updateById($id,$arrSet){
		$this->beginTranscation();
		try {
			parent::updateById($id, $arrSet);
			
			if(isset($arrSet[\haibao\cms\model\filter\User::CONDITION_FIELD_NAME_GROUPS])){
				$this->updateUserGroups($id, $arrSet[\haibao\cms\model\filter\User::CONDITION_FIELD_NAME_GROUPS]);
			}/* else{
				$this->removeUserGroups($id);
			} */
			
			if (isset($arrSet[\haibao\cms\model\filter\User::CONDITION_FIELD_NAME_LEADER_ID])){
				$leadId = $arrSet[\haibao\cms\model\filter\User::CONDITION_FIELD_NAME_LEADER_ID];
				
				$sql = 'delete from UserLeaderMap where Id in (
						select Id from
							(
								select map.Id from UserLeaderMap map inner join (
									select * from
									(
										select a.LeaderId from UserLeaderMap a where a.UserId = %s and a.LeaderId <> %s
									) a
									join
									(
										select b.UserId from UserLeaderMap b where b.LeaderId = %s
									) b
								) tmp ON map.LeaderId = tmp.LeaderId and map.UserId = tmp.UserId
							) a
						)';
				$this->query($sql, array_pad(array(), 3, $id));
					
				$sql = 'insert into UserLeaderMap (UserId, LeaderId) select  b.UserId,a.LeaderId from
						(
							select LeaderId from UserLeaderMap where UserId = %s
						) a join (
							select UserId from UserLeaderMap where LeaderId = %s
						) b';
				$this->query($sql, array(
						$leadId, $id
				));
			}
			
			$this->removeUserCacheById($id);
		} catch (\Exception $e) {
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	/**
	 * 设置用户组用户
	 * @param unknown_type $groupId
	 * @param unknown_type $userIds
	 */
	public function setGroupUser($groupId,$userIds){
		$this->beginTranscation();
		try{
			$sql = 'delete from UserGroup where GroupId=%s and UserId in ('.implode(',', $userIds).')';
			$this->query($sql,array($groupId));
			
			$sql = 'insert into UserGroup(UserId,GroupId) values';
			$arrSql = $arrValues = array();
			foreach($userIds as $userId){
				if($userId){
					array_push($arrSql,'(%s,%s)');
					array_push($arrValues, $userId);
					array_push($arrValues, $groupId);
					$this->removeUserCacheById($userId);
				}
			}
			$sql .= implode(',', $arrSql);
			$this->query($sql, $arrValues);
		} catch (\Exception $e) {
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	public function updateUserGroups($id, $Groups){
		$this->beginTranscation();
		try{
			$this->removeUserGroups($id);
			$this->addUserGroups($id, $Groups);
			//$this->removeUserCacheById($id);
		} catch (\Exception $e) {
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	public function getUserByEmail($email,$isEffect = true){
		$data = null;
		$sql = 'select * from `User` where Email=%s';
		if($isEffect){
			$sql .= 'and Status='.\haibao\cms\model\data\User::STATUS_ENABLE;
		}
		$result = $this->query($sql,array($email));
		while ($row = $result->fetch_assoc()){
			$data = new \haibao\cms\model\data\User();
			$data->loadArray($row);
		}
	
		return $data;
	}
	
	public function getUserByMobile($mobile,$isEffect = true){
		$data = null;
		$sql = 'select * from `User` where Mobile=%s';
		if($isEffect){
			$sql .= 'and Status='.\haibao\cms\model\data\User::STATUS_ENABLE;
		}
		$result = $this->query($sql,array($mobile));
		while ($row = $result->fetch_assoc()){
			$data = new \haibao\cms\model\data\User();
			$data->loadArray($row);
		}
	
		return $data;
	}
	
	public function getUserByJobNum($jobNum){
		$data = null;
		$sql = 'select * from User Where JobNum=%s limit 1';
		$result = $this->query($sql,array($jobNum));
		while ($row = $result->fetch_assoc()){
			$data = new \haibao\cms\model\data\User();
			$data->loadArray($row);
		}
	
		return $data;
	}
	
	public function getUsersByAllName($name){
		$data = array();
		$name = '%' . $name . '%';
		$sql = 'select * from User where RealName like %s or UserName like %s';
		$result = $this->query($sql,array($name,$name));
	
		while ($row = $result->fetch_assoc()){
			$model = new \haibao\cms\model\data\User();
			$model->loadArray($row);
			array_push($data,$model);
		}
	
		return $data;
	}
	
	public function removeUserCacheById($id){
		$cache = new \haibao\cms\cache\User();
		$cache->removeUserById($id);
		$leaderId = $this->getUserLeaderById($id);
		if($leaderId != $id){
			$this->removeUserCacheById($leaderId);
		}
	}
	
	public function removeUserGroups($id){
		$sql = 'delete from UserGroup where UserId=%s';
		$this->query($sql,array($id));
	}

	private function addUserGroups($id, $Groups){
		$sql = 'insert into UserGroup(UserId,GroupId) values';
		$arrSql = $arrValues = array();
		foreach($Groups as $group){
			array_push($arrSql,'(%s,%s)');
			array_push($arrValues, $id);
			array_push($arrValues, $group);
		}
		$sql .= implode(',', $arrSql);
		$this->query($sql, $arrValues);
		$this->removeUserCacheById($id);
	}
	public function getUserNameByIds($ids){

		$userFilter = new UserFilter();
		$userFilter->select(array(
				UserFilter::CONDITION_FIELD_NAME_REAL_NAME,
				UserFilter::CONDITION_FIELD_NAME_USER_NAME,
				UserFilter::CONDITION_FIELD_NAME_ID
		));
		$userFilter->where(UserFilter::CONDITION_FIELD_NAME_ID, \haibao\frame\data\query\Condition::CONDITION_IN, $ids);
		//$userFilter->where(UserFilter::CONDITION_FIELD_NAME_STATUS, \haibao\frame\data\query\Condition::CONDITION_EQUAL, \haibao\cms\model\data\User::STATUS_ENABLE);
		
		$users =  parent::getAll($userFilter);
		$usertNames = array();
		if($users){
			foreach($users as $key=>$user){
				$usertNames[$user->Id] = $user->RealName;
			}
		}
		return $usertNames;
	}
	
	/**
	 * 获取用户的下级用户
	 * @param : $userId 用户ID
	 * @param : $exceptSelf 是否剔除自己，默认为不剔除
	 */
	public function getLowerUserById($userId,$exceptSelf=false){
		$exceptCondition = '';
		$userIdArr = array();
		if($exceptSelf){
			$exceptCondition = ' and UserId <> LeaderId';
		}
		$sql = 'select UserId from `UserLeaderMap` where LeaderId=%s'.$exceptCondition;
		$result = $this->query($sql,array($userId));
		while ($result->fetch_assoc()){

			array_push($userIdArr, $result->getData('UserId'));
		}
		return $userIdArr;
	}
	
	/**
	 * 转移用户下的下属员工
	 * @param :int $userId 用户Id
	 * @param:int $transferId 转移到用户Id
	 */
	public function transferSubUserByLeaderId($userId,$transferId){
		$this->beginTranscation();
		try {
		    $fromUser = $this->getUserById($userId);
		    $toUser = $this->getUserById($transferId);
		    /**
		     * 转移下属用户Leader
		     */
			$filter = new UserFilter();
			$subUserIds = $this->getLowerUserById($userId);
			$filter->where(\haibao\cms\model\filter\User::CONDITION_FIELD_NAME_ID, Condition::CONDITION_IN, $subUserIds);
			$filter->where(\haibao\cms\model\filter\User::CONDITION_FIELD_NAME_ID, Condition::CONDITION_NOTEQUAL, $userId);
			
			if($subUserIds){
                parent::update(array(\haibao\cms\model\filter\User::CONDITION_FIELD_NAME_LEADER_ID =>$transferId), $filter);
			}
			
			/**
			 * 转移用户关系
			 */
			$sql = 'insert into UserLeaderMap (UserId, LeaderId) select  b.UserId,%s from
			(
			select UserId from UserLeaderMap where LeaderId = %s AND UserId <> %s
			) b';
			$this->query($sql, array(
				$transferId,$userId,$userId
			));
			
			$sql = 'delete from UserLeaderMap where LeaderId= %s';
			$this->query($sql, array($userId));
			$this->removeUserCacheById($userId);
			$this->clearUsersCache($subUserIds);
			
			/**
			 * 转移Leader
			 */
			/* if($fromUser->Permission && $fromUser->LeaderId){
			    $this->updateById($transferId, array(
			        'LeaderId' => $fromUser->LeaderId
			    ));
			} */
			
			/**
			 * 转移用户所属组
			 */
			$fromUserGroup = $fromUser->Groups;
			$toUserGroup = $toUser->Groups;
			if($fromUserGroup){
			    $transferGroup = $toUserGroup ? $toUserGroup : array();
			    foreach ($fromUserGroup as $groupId){
			        in_array($groupId, $toUserGroup) ?: array_push($transferGroup, $groupId);
			    }
			    if($transferGroup){
			        $sql = 'insert into UserGroup(UserId, GroupId) values ';
			        $arrSql = $arrValues = array();
			        foreach($transferGroup as $groupId){
			            array_push($arrSql, '(%s,%s)');
			            array_push($arrValues, $transferId);
			            array_push($arrValues, $groupId);
			        }
			        if($arrSql && $arrValues){
			            $sql .= implode(',', $arrSql);
			            $this->query($sql, $arrValues);
			        }
			    }
			}
			
			/**
			 * 转移考勤审核记录
			 */
			$sql = 'update AttendanceRequest set AuditUserId=%s where AuditUserId=%s';
			$this->query($sql,array($transferId,$userId));
		} catch (\Exception $e) {
			$this->rollback();
			throw $e;
		}
		$this->endTranscation();
	}
	
	/**
	 * 根据dingid查询用户信息
	 */
	public function getUserByDingId($dingId){
	    $result = $this->query('select Id,UserName,RealName,Email,PenName,JobNum from User where DingUserId=%s and Status=%s limit 1', array(
	        $dingId,
	        \haibao\cms\model\data\User::STATUS_ENABLE
	    ));
	    return $result->fetch_assoc();
	}
	
	private function clearUsersCache($subUserIds){
		foreach($subUserIds as $userId){
			$this->removeUserCacheById($userId);
		}
	}
	
	private function getUserLeaderById($userId){
		$leaderId = 0;
		$sql = 'select LeaderId from User where Id=%s';
		$result = $this->query($sql,array($userId));
		while ($result->fetch_assoc()){
			$leaderId = $result->getData('LeaderId');
		}
		
		return $leaderId;
	}
	
	public function updateAttendanceUser($id, $arrSet){
		parent::updateById($id, $arrSet);
	}
}
